﻿namespace GreenIsomer.Web.Controls.JQuery {
	using System;
	using System.Web.UI;
	using System.Text;

	/// <summary>
	/// Provides extended instance methods for objects that cannot otherwise have them defined.
	/// </summary>
	public static class Extensions {


		#region Static Methods: Enumeration instance methods

		/// <summary>
		/// Returns the CSS class associated with a symbol defined by the GreenIsomer.Web.Controls.JQuery.Symbol enumeration.
		/// </summary>
		/// <param name="symbol">The GreenIsomer.Web.Controls.JQuery.Symbol enumeration value being extended.</param>
		/// <returns>The associated CSS class.</returns>
		public static string GetCssClass(this Symbol symbol) {
			return SymbolAttribute.GetCssClass(symbol);
		}

		/// <summary>
		/// Returns the CSS class associated with a panel type defined by the GreenIsomer.Web.Controls.JQuery.PanelType enumeration.
		/// </summary>
		/// <param name="panelType">The GreenIsomer.Web.Controls.JQuery.PanelType enumeration value being extended.</param>
		/// <returns>The associated CSS class.</returns>
		public static string GetCssClass(this PanelType panelType) {
			return PanelTypeAttribute.GetCssClass(panelType);
		}

		/// <summary>
		/// Returns the CSS class associated with a priority defined by the GreenIsomer.Web.Controls.JQuery.Priority enumeration.
		/// </summary>
		/// <param name="priority">The GreenIsomer.Web.Controls.JQuery.Priority enumeration value being extended.</param>
		/// <returns>The associated CSS class.</returns>
		public static string GetCssClass(this Priority priority) {
			return PriorityAttribute.GetCssClass(priority);
		}

		#endregion


		#region Static Methods: Interface instance methods

		/// <summary>
		/// Builds a a CSS class referencing classes based on information provided by a GreenIsomer.Web.Controls.JQuery.IThemed implementation.
		/// </summary>
		/// <param name="themedPanel">The GreenIsomer.Web.Controls.JQuery.IThemed implementation being extended.</param>
		/// <returns>The associated CSS class or classes.</returns>
		public static string GetThemedCssClass(this IThemed themedPanel) {
			return GetThemedCssClass(themedPanel, false, false);
		}

		/// <summary>
		/// Builds a a CSS class referencing classes based on information provided by a GreenIsomer.Web.Controls.JQuery.IThemed implementation.
		/// </summary>
		/// <param name="themedControl">The GreenIsomer.Web.Controls.JQuery.IThemed implementation being extended.</param>
		/// <param name="suppressClearFix">When true, do not add the standard jQuery UI "ui-helper-clearfix" class.</param>
		/// <param name="suppressCornerAll">When trye, do not add the standard jQuery UI "ui-corner-all" class.</param>
		/// <returns>The associated CSS class or classes.</returns>
		public static string GetThemedCssClass(this IThemed themedControl, bool suppressClearFix, bool suppressCornerAll) {
			string additionalCssClass = themedControl.CssClass;
			if(!themedControl.UseTheme) return additionalCssClass;

			StringBuilder result = new StringBuilder();

			if(!suppressClearFix) AppendCssClass(result, "ui-helper-clearfix");
			AppendCssClass(result, themedControl.PanelType.GetCssClass());
			if(!themedControl.Enabled) AppendCssClass(result, "ui-state-disabled");
			if(themedControl.Highlight) AppendCssClass(result, "ui-state-highlight");
			if(themedControl.ShowErrorState) AppendCssClass(result, "ui-state-error");
			AppendCssClass(result, themedControl.Priority.GetCssClass());
			if(!suppressCornerAll) AppendCssClass(result, "ui-corner-all");
			AppendCssClass(result, additionalCssClass);

			return result.ToString();
		}

		#endregion


		#region Static Methods: Control instance methods

		internal static string GetClientId(this Control control, string serverId) {

			if(string.IsNullOrEmpty(serverId)) return null;

			Control targetControl = control.NamingContainer.FindControl(serverId);
			if (targetControl == null) return null;
			return targetControl.ClientID;
		}

		#endregion


		#region Static Methods: Internal ViewState (StateBag) instance methods

		internal static T GetValue<T>(this StateBag viewState, string key, T defaultValue) {
			object value = viewState[key];
			if(!(value is T)) return defaultValue;
			return (T)value;
		}

		internal static Nullable<T> GetNullableValue<T>(this StateBag viewState, string key) where T : struct {
			object value = viewState[key];
			if(!(value is T)) return new Nullable<T>();
			return (T)value;
		}

		internal static void SetNullableValue<T>(this StateBag viewState, string key, Nullable<T> value) where T : struct {
			if(value.HasValue) viewState[key] = value.Value;
			else viewState[key] = null;
		}

		#endregion


		#region Static Methods: Private routines

		private static void AppendCssClass(StringBuilder baseCssClass, string cssClass) {
			if(string.IsNullOrEmpty(cssClass)) return;

			if(baseCssClass.Length != 0) baseCssClass.Append(" ");
			baseCssClass.Append(cssClass);
		}

		#endregion


	}

}